[libcxx] Fix PR23589: std::function doesn't recognize null pointer to varargs function. Summary: This patch fixes __not_null's detection of nullptr by breaking it down into 4 cases. 1. `__not_null(Tp const&)`: Default case. Tp is not null. 2. `__not_null(Tp* __ptr);` Case for pointers to functions. 3. `__not_null(_Ret _Class::* __ptr);` Case for pointers to members. 4. `__not_null(function<Tp> const&);`: Cases for other std::functions. Reviewers: mclow.lists Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D11111 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@245335 91177308-0d34-0410-b5e6-96231b3b80d8 
diff --git a/include/functional b/include/functional index 6c57de0..3c9f5a7 100644 --- a/include/functional +++ b/include/functional 
@@ -1327,6 +1327,22 @@  {  };   +template <class _Fp> +_LIBCPP_INLINE_VISIBILITY +bool __not_null(_Fp const&) { return true; } + +template <class _Fp> +_LIBCPP_INLINE_VISIBILITY +bool __not_null(_Fp* __ptr) { return __ptr; } + +template <class _Ret, class _Class> +_LIBCPP_INLINE_VISIBILITY +bool __not_null(_Ret _Class::*__ptr) { return __ptr; } + +template <class _Fp> +_LIBCPP_INLINE_VISIBILITY +bool __not_null(function<_Fp> const& __f) { return !!__f; } +  } // namespace __function    #ifndef _LIBCPP_HAS_NO_VARIADICS @@ -1468,28 +1484,6 @@  typename aligned_storage<3*sizeof(void*)>::type __buf_;  __base* __f_;   - template <class _Fp> - _LIBCPP_INLINE_VISIBILITY - static bool __not_null(const _Fp&) {return true;} - template <class _R2, class ..._Ap> - _LIBCPP_INLINE_VISIBILITY - static bool __not_null(_R2 (*__p)(_Ap...)) {return __p;} - template <class _R2, class _Cp, class ..._Ap> - _LIBCPP_INLINE_VISIBILITY - static bool __not_null(_R2 (_Cp::*__p)(_Ap...)) {return __p;} - template <class _R2, class _Cp, class ..._Ap> - _LIBCPP_INLINE_VISIBILITY - static bool __not_null(_R2 (_Cp::*__p)(_Ap...) const) {return __p;} - template <class _R2, class _Cp, class ..._Ap> - _LIBCPP_INLINE_VISIBILITY - static bool __not_null(_R2 (_Cp::*__p)(_Ap...) volatile) {return __p;} - template <class _R2, class _Cp, class ..._Ap> - _LIBCPP_INLINE_VISIBILITY - static bool __not_null(_R2 (_Cp::*__p)(_Ap...) const volatile) {return __p;} - template <class _R2, class ..._Ap> - _LIBCPP_INLINE_VISIBILITY - static bool __not_null(const function<_R2(_Ap...)>& __p) {return !!__p;} -  template <class _Fp, bool = !is_same<_Fp, function>::value &&  __invokable<_Fp&, _ArgTypes...>::value>  struct __callable; @@ -1654,7 +1648,7 @@  >::type*)  : __f_(0)  { - if (__not_null(__f)) + if (__function::__not_null(__f))  {  typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_ArgTypes...)> _FF;  if (sizeof(_FF) <= sizeof(__buf_) && is_nothrow_copy_constructible<_Fp>::value) @@ -1681,7 +1675,7 @@  : __f_(0)  {  typedef allocator_traits<_Alloc> __alloc_traits; - if (__not_null(__f)) + if (__function::__not_null(__f))  {  typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _FF;  typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;